package com.lingjtx.iot.network.handle;

import com.alibaba.fastjson2.JSONObject;
import com.lingjtx.common.core.RedisOptions;
import com.lingjtx.common.core.handle.Injector;
import com.lingjtx.common.core.model.iot.DeviceBaseInfo;
import com.lingjtx.common.core.util.StringUtil;

public interface MqttDataHandler<Data> {

    /**
     * 将物联网设备上报数据按照 TSL（物模型）转化为标准化的数据对象。
     */
    Data convertData(String productId, JSONObject json);

    /**
     * 将数据写入时序数据库（如 InfluxDB）。
     */
    void insertToInfluxDB(DeviceBaseInfo device, Data data);

    /**
     * 更新 Redis 缓存。
     */
    void updateRedis(DeviceBaseInfo device, Data data, RedisOptions redis);

    /**
     * 处理设备故障（告警等）。
     */
    void handleDeviceFault(DeviceBaseInfo device, Data data, RedisOptions redis, Injector dao);

    /**
     * 当主动下发刷新数据命令后或设备首次添加时，设备上报的数据含有 requestId 字段
     */
    void refreshData(DeviceBaseInfo device, Data data);

    /**
     * 主统一处理方法。根据 isFault 参数判断是否为告警上报。
     */
    default void handle(DeviceBaseInfo device, JSONObject json, RedisOptions redis, Injector dao, boolean isFault) {
        if (device == null || json == null || json.isEmpty()) {
            throw new IllegalArgumentException("参数无效：device 或 json 为 null/empty");
        }

        Data data = convertData(device.getProductId(), json);
        if (data == null) {
            throw new IllegalStateException("数据转换失败，convertData 返回 null");
        }

        if (isFault) {
            handleDeviceFault(device, data, redis, dao);
        } else {
            String requestId = json.getString("requestId");
            if (StringUtil.isNotEmpty(requestId)) {
                refreshData(device, data);
            }
            insertToInfluxDB(device, data);
            updateRedis(device, data, redis);
        }
    }
}
